package lc.com.lcpicturebackend.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lc.com.lcpicturebackend.constant.ThumbConstant;
import lc.com.lcpicturebackend.exception.BusinessException;
import lc.com.lcpicturebackend.exception.ErrorCode;
import lc.com.lcpicturebackend.mapper.ThumbMapper;
import lc.com.lcpicturebackend.model.dto.thumb.DoThumbRequest;
import lc.com.lcpicturebackend.model.entity.Picture;
import lc.com.lcpicturebackend.model.entity.Thumb;
import lc.com.lcpicturebackend.model.entity.User;
import lc.com.lcpicturebackend.service.PictureService;
import lc.com.lcpicturebackend.service.ThumbService;
import lc.com.lcpicturebackend.service.UserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;

import static net.sf.jsqlparser.util.validation.metadata.MetadataContext.exists;

/**
 * @author 罗超
 * @description 针对表【thumb】的数据库操作Service实现
 * @createDate 2025-05-03 01:25:41
 */
@Service
public class ThumbServiceImpl extends ServiceImpl<ThumbMapper, Thumb>
        implements ThumbService {

    @Resource
    private UserService userService;

    @Resource
    private TransactionTemplate transactionTemplate;

    @Resource
    private PictureService pictureService;

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Boolean doThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {

        User loginUser = userService.getLoginUser(request);

        // 加锁防止并发
        synchronized (loginUser.getId().toString().intern()) {
            // 编程式事务
            return transactionTemplate.execute(status -> {
                Long pictureId = doThumbRequest.getPictureId();
                // 判断是否已经点赞过
                // boolean exists = this.lambdaQuery()
                //         .eq(Thumb::getPictureId, pictureId)
                //         .eq(Thumb::getUserId, loginUser.getId())
                //         .exists();

                boolean exists = this.hasThumb(pictureId, loginUser.getId());
                if (exists) {
                    // 已经点赞过，则取消点赞
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "已经点赞过");
                }
                // 没有点赞，首先进行点赞+1
                boolean update = pictureService.lambdaUpdate()
                        .eq(Picture::getId, pictureId)
                        .setSql("thumbCount = thumbCount + 1")
                        .update();
                // 然后记录点赞记录
                Thumb thumb = new Thumb();
                thumb.setPictureId(pictureId);
                thumb.setUserId(loginUser.getId());
                // 更新成功才执行
                boolean result = update && this.save(thumb);
                if (result){
                    redisTemplate.opsForHash().put(ThumbConstant.USER_THUMB_KEY_PREFIX+loginUser.getId().toString(),
                            pictureId.toString(),
                            thumb.getId());
                }
                return result;
            });
        }


    }

    @Override
    public Boolean undoThumb(DoThumbRequest doThumbRequest, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        Long userId = loginUser.getId();
        // 加锁
        synchronized (loginUser.getId().toString().intern()){
            return transactionTemplate.execute(status -> {
                // 查询是否已经点赞
                Long pictureId = doThumbRequest.getPictureId();
                Thumb thumb = this.lambdaQuery()
                        .eq(Thumb::getPictureId, pictureId)
                        .eq(Thumb::getUserId, loginUser.getId())
                        .one();
                // 如果未点赞，则抛出异常
                if (thumb==null) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "未点赞");
                }
                // 如果已经点赞，则取消点赞
                boolean update = pictureService.lambdaUpdate()
                        .eq(Picture::getId, pictureId)
                        .setSql("thumbCount = thumbCount - 1")
                        .update();
                // 删除点赞记录
                redisTemplate.opsForHash().delete(ThumbConstant.USER_THUMB_KEY_PREFIX+userId,pictureId.toString());
                return update && this.removeById(thumb.getId());
            });
        }
    }

    @Override
    public Boolean hasThumb(Long pictureId, Long userId) {
        return redisTemplate.opsForHash().hasKey(ThumbConstant.USER_THUMB_KEY_PREFIX+userId,pictureId.toString());
    }
}




